/**
 * Licensed to CMIM,Inc. under the terms of the CMIM * Software License version 1.0.
 * See the NOTICE file distributed with this work for additional * information regarding copyright ownership.
 * ---------------------------------------------------------------------------- * Date Author Version
 * 2019/3/16 neusoft 1.0
 **/

package com.xnyzc.lhy.common.util.gps;

import com.alibaba.fastjson.JSONObject;
import com.xnyzc.lhy.common.util.http.HttpRequestUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.client.ClientProtocolException;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 高德谷歌系天朝纠偏算法
 * @author none
 *
 */
public class GpsCorrect {
    final static double pi = 3.14159265358979324;
    final static double a = 6378245.0;
    final static double ee = 0.00669342162296594323;
    private static final String GET_LOCATION_TRANS_URL = "http://restapi.amap.com/v3/assistant/coordinate/convert";
    
    public static String[] transform(String wgLat, String wgLon, String coordsys) throws ClientProtocolException, IOException{
    	String[] latlng = new String[2];
    	String key ="ff96564b30c4e72e98540c11d3679c7b";
		Map<String,Object> paramMap = new HashMap<String,Object>();
		
		paramMap.put("key", key);
		paramMap.put("locations", wgLon + "," + wgLat);
		paramMap.put("coordsys", coordsys);
		paramMap.put("sig", getSign(paramMap)); 
		
		String result = HttpRequestUtil.request(GET_LOCATION_TRANS_URL, paramMap, "get", "UTF-8");
		JSONObject resultJson = JSONObject.parseObject(result);
		String status = resultJson.getString("status");
		
		if("1".equals(status)) {
			String location = resultJson.getString("locations");
			latlng = location.split(",");
		}
		
		return latlng;
    }
    public static void transform(double wgLat, double wgLon, double[] latlng) {
        if (outOfChina(wgLat, wgLon)) {
            latlng[0] = wgLat;
            latlng[1] = wgLon;
            return;
        }
        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        latlng[0] = wgLat + dLat;
        latlng[1] = wgLon + dLon;
    }
 
    private static boolean outOfChina(double lat, double lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    }
 
    private static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }
 
    private static double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
        return ret;
    }
    
    public static String getSign(Map<String,Object> paramMap) {
		if(paramMap.size() > 0) {
			
			String signKey ="ced3d682776551f55f1e090b53104378";
			int count = paramMap.size();
			String [] paramKey = new String[count];
			Iterator<Entry<String, Object>> it = paramMap.entrySet().iterator();
			int a = 0;
			while(it.hasNext()) {
				Entry<String, Object> entry = it.next();
				String mapKey = entry.getKey();
				paramKey[a] = mapKey;
				a++;
			}
			Arrays.sort(paramKey);
			StringBuffer signBuffer = new StringBuffer();
			for(int i = 0;i < paramKey.length;i++) {
				signBuffer.append(paramKey[i]);
				signBuffer.append("=");
				signBuffer.append(paramMap.get(paramKey[i]));
				signBuffer.append("&");
			}
			String param = signBuffer.substring(0, signBuffer.lastIndexOf("&"));
			String sign = DigestUtils.md5Hex(param + signKey);
			return sign;
		}
	    return "";
	}
}
